home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1995, 1996, 1997, 1999, 2000 Aladdin Enterprises. All rights reserved.
-
- This file is part of AFPL Ghostscript.
-
- AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
- distributor accepts any responsibility for the consequences of using it, or
- for whether it serves any particular purpose or works at all, unless he or
- she says so in writing. Refer to the Aladdin Free Public License (the
- "License") for full details.
-
- Every copy of AFPL Ghostscript must include a copy of the License, normally
- in a plain ASCII text file named PUBLIC. The License grants you the right
- to copy, modify and redistribute AFPL Ghostscript, but only under certain
- conditions described in the License. Among other things, the License
- requires that the copyright notice and this notice be preserved on all
- copies.
- */
-
- /*$Id: gxdht.h,v 1.4 2000/09/19 19:00:36 lpd Exp $ */
- /* Definition of device halftones */
-
- #ifndef gxdht_INCLUDED
- # define gxdht_INCLUDED
-
- #include "gsrefct.h"
- #include "gscsepnm.h"
- #include "gsmatrix.h"
- #include "gxarith.h" /* for igcd */
- #include "gxhttype.h"
-
- /*
- * We represent a halftone tile as a rectangular super-cell consisting of
- * multiple copies of a multi-cell whose corners lie on integral
- * coordinates, which in turn is a parallelogram (normally square) array of
- * basic parallelogram (normally square) cells whose corners lie on rational
- * coordinates.
- *
- * Let T be the aspect ratio (ratio of physical pixel height to physical
- * pixel width), which is abs(xx/yy) for portrait devices and abs(yx/xy) for
- * landscape devices. We characterize the basic cell by four rational
- * numbers U(') = M(')/R(') and V(') = N(')/R(') where R(') is positive, at
- * least one of U and V (and the corresponding one of U' and V') is
- * non-zero, and U' is approximately U/T and V' is approximately V*T; these
- * numbers define the vertices of the basic cell at device space coordinates
- * (0,0), (U,V), (U-V',U'+V), and (-V',U'); then the multi-cell is defined
- * similarly by M(') and N('). From these definitions, the basic cell has
- * an area of B = U*U' + V*V' = (M*M' + N*N') / R*R' pixels, and the
- * multi-cell has an area of C = B * R*R' = M*M' + N*N' pixels.
- *
- * If the coefficients of the default device transformation matrix are xx,
- * xy, yx, and yy, then U and V are related to the frequency F and the angle
- * A by:
- * P = 72 / F;
- * U = P * (xx * cos(A) + yx * sin(A));
- * V = P * (xy * cos(A) + yy * sin(A)).
- *
- * We can tile the plane with any rectangular super-cell that consists of
- * repetitions of the multi-cell and whose corners coincide with multi-cell
- * coordinates (0,0). We observe that for any integers i, j such that i*N -
- * j*M' = 0, a multi-cell corner lies on the X axis at W = i*M + j*N';
- * similarly, if i'*M - j'*N' = 0, a corner lies on the Y axis at W' = i'*N
- * + j'*M'. Then the super-cell occupies Z = W * W' pixels, consisting of Z
- * / C multi-cells or Z / B basic cells. The trick in all this is to find
- * values of F and A that aren't too far from the requested ones, and that
- * yield a manageably small value for Z.
- *
- * Note that the super-cell only has to be so large because we want to use
- * it directly to tile the plane. In fact, we can decompose it into W' / D
- * horizontal strips of width W and height D, shifted horizontally with
- * respect to each other by S pixels, where we compute S by finding h and k
- * such that h*N - k*M' = D and then S = h*M + k*N'. The halftone setup
- * routines only generate a single strip of samples, and let
- * gx_ht_construct_spot_order construct the rest. If W' is large, we
- * actually keep only one strip, and let the strip_tile_rectangle routines
- * do the shifting at rendering time.
- */
- typedef struct gx_ht_cell_params_s {
- /* Defining values. M * M1 != 0 or N * N1 != 0; R > 0, R1 > 0. */
- /* R and D are short rather than ushort so that we don't get */
- /* unsigned results from arithmetic. */
- short M, N, R;
- short M1, N1, R1;
- /* Derived values. */
- ulong C;
- short D, D1;
- uint W, W1;
- int S;
- } gx_ht_cell_params_t;
-
- /* Compute the derived values from the defining values. */
- void gx_compute_cell_values(P1(gx_ht_cell_params_t *));
-
- /*
- * The whitening order is represented by a pair of arrays.
- * The levels array contains an integer (an index into the bit_data array)
- * for each distinct halftone level, indicating how many pixels should be
- * whitened for that level; levels[0] = 0, levels[i] <= levels[i+1], and
- * levels[num_levels-1] <= num_bits. The bit_data array contains data to
- * specify which bits should be set for each level: it has several
- * different representations depending on space/time tradeoffs.
- *
- * The default bit_data representation is an (offset,mask) pair for each
- * pixel in the tile. bits[i].offset is the (properly aligned) byte index
- * of a pixel in the tile; bits[i].mask is the mask to be or'ed into this
- * byte and following ones. This is arranged so it will work properly on
- * either big- or little-endian machines, and with different mask widths.
- */
- /*
- * The mask width must be at least as wide as uint,
- * and must not be wider than the width implied by align_bitmap_mod.
- */
- typedef uint ht_mask_t;
-
- #define ht_mask_bits (sizeof(ht_mask_t) * 8)
- typedef struct gx_ht_bit_s {
- uint offset;
- ht_mask_t mask;
- } gx_ht_bit;
-
- /* During sampling, bits[i].mask is used to hold a normalized sample value. */
- typedef ht_mask_t ht_sample_t;
-
- /* The following awkward expression avoids integer overflow. */
- #define max_ht_sample (ht_sample_t)(((1 << (ht_mask_bits - 2)) - 1) * 2 + 1)
-
- /*
- * Define the internal representation of a halftone order.
- * Note that it may include a cached transfer function.
- *
- * Halftone orders exist in two slightly different configurations, strip and
- * complete. In a complete order, shift = 0 and full_height = height; in a
- * strip order, shift != 0 and full_height is the height of a fully expanded
- * halftone made up of enough shifted strip copies to get back to a zero
- * shift. In other words, full_height is a cached value, but it is an
- * important one, since it is the modulus used for computing the
- * tile-relative phase. Requirements:
- * width > 0, height > 0, multiple > 0
- * raster >= bitmap_raster(width)
- * 0 <= shift < width
- * num_bits = width * height
- * For complete orders:
- * full_height = height
- * For strip orders:
- * full_height = height * width / gcd(width, shift)
- * Note that during the sampling of a complete spot halftone, these
- * invariants may be violated; in particular, it is possible that shift != 0
- * and height < full_height, even though num_bits and num_levels reflect the
- * full height. In this case, the invariant is restored (by resetting
- * shift and height) when sampling is finished. However, we must save the
- * original height and shift values used for sampling, since sometimes we
- * run the "finishing" routines more than once. (This is ugly, but it's
- * too hard to fix.)
- *
- * See gxbitmap.h for more details about strip halftones.
- */
- typedef struct gx_ht_cache_s gx_ht_cache;
- #ifndef gx_ht_order_DEFINED
- # define gx_ht_order_DEFINED
- typedef struct gx_ht_order_s gx_ht_order;
- #endif
- #ifndef gx_ht_tile_DEFINED
- # define gx_ht_tile_DEFINED
- typedef struct gx_ht_tile_s gx_ht_tile;
- #endif
- typedef struct gx_ht_order_procs_s {
-
- /* Define the size of each element of bit_data. */
-
- uint bit_data_elt_size;
-
- /* Construct the order from the threshold array. */
- /* Note that for 16-bit threshold values, */
- /* each value is 2 bytes in big-endian order (Adobe spec). */
-
- int (*construct_order)(P2(gx_ht_order *order, const byte *thresholds));
-
- /* Return the (x,y) coordinate of an element of bit_data. */
-
- int (*bit_index)(P3(const gx_ht_order *order, uint index,
- gs_int_point *ppt));
-
- /* Update a halftone cache tile to match this order. */
-
- int (*render)(P3(gx_ht_tile *tile, int new_bit_level,
- const gx_ht_order *order));
-
- } gx_ht_order_procs_t;
- /*
- * Define the procedure vectors for the supported implementations
- * (in gxhtbit.c).
- */
- extern const gx_ht_order_procs_t ht_order_procs_table[2];
- #define ht_order_procs_default ht_order_procs_table[0] /* bit_data is gx_ht_bit[] */
- #define ht_order_procs_short ht_order_procs_table[1] /* bit_data is ushort[] */
- /* For screen/spot halftones, we must record additional parameters. */
- typedef struct gx_ht_order_screen_params_s {
- gs_matrix matrix; /* CTM when the function was sampled */
- ulong max_size; /* max bitmap size */
- } gx_ht_order_screen_params_t;
- struct gx_ht_order_s {
- gx_ht_cell_params_t params; /* parameters defining the cells */
- ushort width;
- ushort height;
- ushort raster;
- ushort shift;
- ushort orig_height;
- ushort orig_shift;
- uint full_height;
- uint num_levels; /* = levels size */
- uint num_bits; /* = countof(bit_data) = width * height */
- const gx_ht_order_procs_t *procs;
- gs_memory_t *data_memory; /* for levels and bit_data, may be 0 */
- uint *levels;
- void *bit_data;
- gx_ht_cache *cache; /* cache to use */
- gx_transfer_map *transfer; /* TransferFunction or 0 */
- gx_ht_order_screen_params_t screen_params;
- };
-
- #define ht_order_is_complete(porder)\
- ((porder)->shift == 0)
- #define ht_order_full_height(porder)\
- ((porder)->shift == 0 ? (porder)->height :\
- (porder)->width / igcd((porder)->width, (porder)->shift) *\
- (porder)->height)
-
- /* We only export st_ht_order for use in st_screen_enum. */
- extern_st(st_ht_order);
- #define public_st_ht_order() /* in gsht.c */\
- gs_public_st_composite(st_ht_order, gx_ht_order, "gx_ht_order",\
- ht_order_enum_ptrs, ht_order_reloc_ptrs)
- #define st_ht_order_max_ptrs 4
-
- /*
- * Define a device halftone. This consists of one or more orders.
- * If components = 0, then order is the only current halftone screen
- * (set by setscreen, Type 1 sethalftone, Type 3 sethalftone, or
- * Type 5 sethalftone with only a Default). Otherwise, order is the
- * gray or black screen (for gray/RGB or CMYK devices respectively),
- * and components is an array of gx_ht_order_components parallel to
- * the components of the client halftone (set by setcolorscreen or
- * Type 5 sethalftone).
- *
- * Multi-component halftone orders may be required even in Level 1 systems,
- * because they are needed for setcolorscreen.
- *
- * NOTE: it is assumed that all subsidiary structures of device halftones
- * (the components array, and the bit_data, levels, cache, and transfer
- * members of any gx_ht_orders, both the default order and any component
- * orders) are allocated with the same allocator as the device halftone
- * itself.
- */
- typedef struct gx_ht_order_component_s {
- gx_ht_order corder;
- gs_ht_separation_name cname;
- } gx_ht_order_component;
-
- #define private_st_ht_order_component() /* in gsht.c */\
- gs_private_st_ptrs_add0(st_ht_order_component, gx_ht_order_component,\
- "gx_ht_order_component", ht_order_component_enum_ptrs,\
- ht_order_component_reloc_ptrs, st_ht_order, corder)
- #define st_ht_order_component_max_ptrs st_ht_order_max_ptrs
- /* We only export st_ht_order_component_element for use in banding. */
- extern_st(st_ht_order_component_element);
- #define public_st_ht_order_comp_element() /* in gsht.c */\
- gs_public_st_element(st_ht_order_component_element, gx_ht_order_component,\
- "gx_ht_order_component[]", ht_order_element_enum_ptrs,\
- ht_order_element_reloc_ptrs, st_ht_order_component)
-
- #ifndef gx_device_halftone_DEFINED
- # define gx_device_halftone_DEFINED
- typedef struct gx_device_halftone_s gx_device_halftone;
- #endif
-
- /*
- * color_indices is a cache that gives the indices in components of
- * the screens for the 1, 3, or 4 primary color(s). These indices are
- * always in the same order, namely:
- * -,-,-,W(gray)
- * R,G,B,-
- * C,M,Y,K
- */
- struct gx_device_halftone_s {
- gx_ht_order order; /* must be first, for subclassing */
- rc_header rc;
- gs_id id; /* the id changes whenever the data change */
- /*
- * We have to keep the halftone type so that we can pass it
- * through the band list for gx_imager_dev_ht_install.
- */
- gs_halftone_type type;
- gx_ht_order_component *components;
- uint num_comp;
- /* The following are computed from the above. */
- uint color_indices[4];
- int lcm_width, lcm_height; /* LCM of primary color tile sizes, */
- /* max_int if overflowed */
- };
-
- extern_st(st_device_halftone);
- #define public_st_device_halftone() /* in gsht.c */\
- gs_public_st_ptrs_add1(st_device_halftone, gx_device_halftone,\
- "gx_device_halftone", device_halftone_enum_ptrs,\
- device_halftone_reloc_ptrs, st_ht_order, order, components)
- #define st_device_halftone_max_ptrs (st_ht_order_max_ptrs + 1)
-
- /* Complete a halftone order defined by a threshold array. */
- void gx_ht_complete_threshold_order(P1(gx_ht_order *porder));
-
- /* Release a gx_device_halftone by freeing its components. */
- /* (Don't free the gx_device_halftone itself.) */
- void gx_device_halftone_release(P2(gx_device_halftone * pdht,
- gs_memory_t * mem));
-
- #endif /* gxdht_INCLUDED */
-